package com.lu.config;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.*;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
import org.springframework.boot.jackson.JsonComponent;
import org.springframework.context.annotation.Bean;

import java.io.IOException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.TimeZone;

/**
 * @Description: 时间配置
 * @Author: zhanglu
 * @Date: 2022/8/27 10:43
 */
@JsonComponent
public class DateFormatConfig {

  @Value("${spring.jackson.date-format:yyyy-MM-dd HH:mm:ss}")
  private String pattern;

  /**
   * @author xiaofu
   * @description date 类型全局时间格式化
   * @date 2020/8/31 18:22
   */
  @Bean
  public Jackson2ObjectMapperBuilderCustomizer jackson2ObjectMapperBuilder() {

    return builder -> {
      TimeZone tz = TimeZone.getTimeZone("UTC");
      DateFormat df = new SimpleDateFormat(pattern);
      df.setTimeZone(tz);
      builder.failOnEmptyBeans(false)
          .failOnUnknownProperties(false)
          .featuresToDisable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
          .dateFormat(df);
    };
  }

//  @Bean
//  public LocalDateTimeSerializer localDateTimeDeserializer() {
//    return new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(pattern));
//  }

  @Bean
  public Jackson2ObjectMapperBuilderCustomizer jackson2ObjectMapperBuilderCustomizer() {
    return builder -> {
      builder.serializerByType(LocalDateTime.class, new LocalDateTimeSerializer());
      builder.deserializerByType(LocalDateTime.class, new LocalDateTimeDeserializer());
    };
  }

  /**
   * 序列化
   */
  public static class LocalDateTimeSerializer extends JsonSerializer<LocalDateTime> {
    @Override
    public void serialize(LocalDateTime value, JsonGenerator gen, SerializerProvider serializers)
            throws IOException {
      if (value != null) {
        long timestamp = value.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
        gen.writeNumber(timestamp);
      }
    }
  }

  /**
   * 反序列化
   */
  public static class LocalDateTimeDeserializer extends JsonDeserializer<LocalDateTime> {
    @Override
    public LocalDateTime deserialize(JsonParser p, DeserializationContext deserializationContext)
            throws IOException {
      long timestamp = p.getValueAsLong();
      if (timestamp > 0) {
        return LocalDateTime.ofInstant(Instant.ofEpochMilli(timestamp), ZoneId.systemDefault());
      } else {
        return null;
      }
    }
  }

}
